package com.ruoyi.merchant.shop.service.impl;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.core.utils.HttpUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.merchant.shop.service.SmsService;

/**
 * 短信服务实现类
 *
 * @author ZheRan
 * @date 2025-09-16
 */
@Service
public class SmsServiceImpl implements SmsService {

    @Autowired
    private RedisService redisService;

    // 短信服务配置
    private static final String HOST = "https://gyytz.market.alicloudapi.com";
    private static final String PATH = "/sms/smsSend";
    private static final String METHOD = "POST";
    private static final String APPCODE = "9b9a4e3b2c8b461bb94bc854709e8f93";
    private static final String SMS_SIGN_ID = "2e65b1bb3d054466b82f0c9d125465e2";
    private static final String TEMPLATE_ID = "908e94ccf08b4476ba6c876d13f084ad";

    // Redis缓存键前缀
    private static final String SMS_CODE_PREFIX = "sms:code:";
    private static final String SMS_LIMIT_PREFIX = "sms:limit:";

    // 验证码有效期（分钟）
    private static final int CODE_EXPIRE_MINUTES = 5;
    // 发送频率限制（秒）
    private static final int SEND_LIMIT_SECONDS = 60;

    @Override
    public String sendCode(String mobile) {
        // 参数验证
        if (StringUtils.isEmpty(mobile) || !isValidMobile(mobile)) {
            return "手机号格式不正确";
        }

        // 检查发送频率限制
        if (!canSend(mobile)) {
            return "发送过于频繁，请稍后再试";
        }

        try {
            // 生成6位随机验证码
            String code = generateCode();

            // 发送短信
            String result = sendSms(mobile, code);
            System.out.println("result:" + result);
            if ("success".equals(result)) {
                // 存储验证码到Redis，设置5分钟过期
                String codeKey = SMS_CODE_PREFIX + mobile;
                redisService.setCacheObject(codeKey, code, (long) CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);

                // 设置发送频率限制
                String limitKey = SMS_LIMIT_PREFIX + mobile;
                redisService.setCacheObject(limitKey, "1", (long) SEND_LIMIT_SECONDS, TimeUnit.SECONDS);

                return "验证码发送成功";
            } else {
                return "验证码发送失败：" + result;
            }

        } catch (Exception e) {
            return "验证码发送异常：" + e.getMessage();
        }
    }

    /**
     * 发送注册的短信
     */
    @Override
    public String sendMsg(String mobile, Integer flag) {
        // 参数验证
        if (StringUtils.isEmpty(mobile) || !isValidMobile(mobile)) {
            return "手机号格式不正确";
        }

        // 检查发送频率限制
        if (!canSend(mobile)) {
            return "发送过于频繁，请稍后再试";
        }

        try {
            String code = null;
            //生成注册信息的短信格式
            if (flag == 0) {
                code = "000000";
            } else {
                code = "111111";
            }

            // 发送短信
            String result = sendSms(mobile, code);
            System.out.println("result:" + result);
            if ("success".equals(result)) {
                // 存储验证码到Redis，设置5分钟过期
                String codeKey = SMS_CODE_PREFIX + mobile;
                redisService.setCacheObject(codeKey, code, (long) CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);

                // 设置发送频率限制
                String limitKey = SMS_LIMIT_PREFIX + mobile;
                redisService.setCacheObject(limitKey, "1", (long) SEND_LIMIT_SECONDS, TimeUnit.SECONDS);

                return "验证码发送成功";
            } else {
                return "验证码发送失败：" + result;
            }

        } catch (Exception e) {
            return "验证码发送异常：" + e.getMessage();
        }
    }

    @Override
    public boolean verifyCode(String mobile, String code) {
        if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(code)) {
            return false;
        }

        String codeKey = SMS_CODE_PREFIX + mobile;
        String cachedCode = redisService.getCacheObject(codeKey);

        if (StringUtils.isEmpty(cachedCode)) {
            return false;
        }

        boolean isValid = code.equals(cachedCode);
        if (isValid) {
            // 验证成功后删除验证码
            redisService.deleteObject(codeKey);
        }

        return isValid;
    }

    @Override
    public boolean canSend(String mobile) {
        String limitKey = SMS_LIMIT_PREFIX + mobile;
        return !redisService.hasKey(limitKey);
    }

    /**
     * 发送短信
     *
     * @param mobile 手机号
     * @param code   验证码
     * @return 发送结果
     */
    private String sendSms(String mobile, String code) {
        try {
            // 构建请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Authorization", "APPCODE " + APPCODE);

            // 构建查询参数
            Map<String, String> querys = new HashMap<>();
            querys.put("mobile", mobile);
            querys.put("param", "**code**:" + code + ",**minute**:5");
            querys.put("smsSignId", SMS_SIGN_ID);
            querys.put("templateId", TEMPLATE_ID);

            // 构建请求体
            Map<String, String> bodys = new HashMap<>();

            // 发送HTTP请求
            String response = HttpUtils.doPost(HOST, PATH, METHOD, headers, querys, bodys);

            // 解析响应结果（根据实际API响应格式调整）
            if (response.contains("\"code\":\"0\"")) {
                return "success";
            } else {
                return response;
            }

        } catch (Exception e) {
            return "发送异常：" + e.getMessage();
        }
    }

    /**
     * 生成6位随机验证码
     *
     * @return 验证码
     */
    private String generateCode() {
        Random random = new Random();
        int code = 100000 + random.nextInt(900000);
        return String.valueOf(code);
    }

    /**
     * 验证手机号格式
     *
     * @param mobile 手机号
     * @return 是否有效
     */
    private boolean isValidMobile(String mobile) {
        return mobile.matches("^1[3-9]\\d{9}$");
    }
}
